package com.ifonly.core;

import com.ifonly.config.Configuration;

import java.util.*;

/**
 * @author <a href="mailto:ifonlymaster@163.com">ifonly</a>
 * @version 1.0 2015-12-09 16:23
 * @since JDK 1.6
 */
public class ClassContainer {

    // ~~ ClassContainer 采用单例模式 ~~

    private ClassContainer() {
    }

    private static class InstanceHolder {
        public static ClassContainer instance;;
    }

    public static synchronized ClassContainer getInstance(Class<?>...classes) {
        if(InstanceHolder.instance == null) {
            InstanceHolder.instance = new ClassContainer();

            if (classes != null && classes.length > 0) {
                for (Class<?> clazz : classes) {
                    InstanceHolder.instance.groupOfClass.put(clazz, new ArrayList<Class<?>>());
                }
            }
        }
        return InstanceHolder.instance;
    }

    private Map<Class<?>, List<Class<?>>> groupOfClass = new HashMap<Class<?>, List<Class<?>>>();

    public void fillGroup(List<Class<?>> classes) {
        Set<Map.Entry<Class<?>, List<Class<?>>>> entries = groupOfClass.entrySet();
        for (Map.Entry<Class<?>, List<Class<?>>> entry : entries) {
            Class<?> key = entry.getKey();
            List<Class<?>> value = entry.getValue();

            for (Class<?> target : classes) {
                if (key.isAssignableFrom(target)) {
                    value.add(target);
                }
            }
        }
        classes.clear();
    }

    public <T> List<Class<?>> group(Class<? extends T> key) {
        return groupOfClass.get(key);
    }

    public Set<Class<?>> groupTypes() {
        return groupOfClass.keySet();
    }

    public Class<?>[] groupTypesArray() {
        Set<Class<?>> set = groupOfClass.keySet();

        Class<?>[] classes = new Class[set.size()];
        int i = 0;
        for (Class<?> clazz : set) {
            classes[i++] = clazz;
        }
        return classes;
    }

    public void destroy() {
        if (!Configuration.getInstance().isDevMode()) {
            groupOfClass.clear();
        }
    }

}
